// 弹窗复选
import React from 'react';
import { Modal, Checkbox, Tree, Input } from 'antd';
import { CloseOutlined, SearchOutlined, MobileOutlined, MailOutlined } from '#/utils/antdIcons';
import TRNotification from '#/utils/notification';
import { TRDefault } from '@/components';

import styles from './index.less';

class ModalComponent extends React.Component {
  constructor(props) {
    super(props);
    const { treeData = [] } = props;
    this.state = {
      visible: true,
      checkAll: false,
      indeterminate: false,
      autoExpandParent: true,
      checkedKeys: [],
      checkedNodes: [],
      expandedKeys: [],
      searchValue: '',
    };
    this.deepLv = 1; // 最深叶子等级
    this.treeDataMap = this._tree2map(treeData, [], null, 1);
    this.allData = treeData;
    this.treeData = treeData;
    this.leafNodes = this.treeDataMap
      .filter((x) => x.lv === this.deepLv)
      .filter((x) => !x.disabled);

    this._onSearch = this._onSearch.bind(this); // 搜索
    this._onChangeAll = this._onChangeAll.bind(this); // 全选
    this._onClearAll = this._onClearAll.bind(this); // 清空
    this._onCheckTree = this._onCheckTree.bind(this); // 树选择
    this._onExpandTree = this._onExpandTree.bind(this); // 树展开
    this._onCancel = this._onCancel.bind(this); // 取消
    this._onOk = this._onOk.bind(this); // 提交
  }

  componentDidMount() {
    this._onCheckTree(this.props.value);
  }

  _tree2map = (tree = [], list = [], parentKey = null, lv = 1) => {
    // 降维,key要唯一
    if (lv > this.deepLv) this.deepLv = lv;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      const { key, title, disabled, phone, email } = node;
      node.lv = lv;
      node.parentKey = parentKey;
      list.push({
        key,
        title,
        disabled,
        parentKey,
        lv,
        phone,
        email,
      });
      if (node.children) {
        this._tree2map(node.children, list, node.key, lv + 1);
      }
    }
    return list;
  };

  _isChinese = (s) => {
    // 中文全匹配
    var ret = true;
    for (var i = 0; i < s.length; i++) ret = ret && s.charCodeAt(i) >= 10000;
    return ret;
  };

  _onSearch = (e) => {
    let expandedKeys = [];
    const { value } = e.target;
    let { checkedKeys, checkedNodes } = this.state;
    if (value && this._isChinese(value)) {
      expandedKeys = this.treeDataMap
        .map((x) => (x.title.indexOf(value) > -1 ? x.parentKey : null))
        .filter((item, i, self) => item && self.indexOf(item) === i);
    }
    if (expandedKeys?.[0]) {
      this.refTree.scrollTo({ key: expandedKeys?.[0], align: 'top' });
    } else {
      this.refTree.scrollTo({ key: 0, align: 'top' });
    }
    const _data = this.allData.filter((t) => {
      if (t?.title?.includes(value) || t?.phone?.includes(value) || t?.email?.includes(value))
        return true;
    });

    this.treeData = _data;
    const checkAll =
      !!checkedKeys.length &&
      checkedNodes.length >= this.treeData.length &&
      this.treeData.every((t) => checkedKeys.includes(t.key));
    const indeterminate =
      !!checkedKeys.length && !checkAll && this.treeData.length > checkedNodes.length;
    this.setState({
      expandedKeys,
      searchValue: value,
      autoExpandParent: true,
      indeterminate,
      checkAll,
      // treeData:_data
    });
  };

  _onChangeAll = (e) => {
    const checkAll = e.target.checked,
      checkedNodes = checkAll
        ? [
            ...(this.state.checkedNodes || []).filter(
              (t) => !this.treeData.map((_t) => _t.key).includes(t.key),
            ),
            ...this.treeData,
          ]
        : [...this.allData.filter((t) => !this.treeData.map((_t) => _t.key).includes(t.key))],
      checkedKeys = checkedNodes.map((x) => x.key);
    this.setState({
      checkAll,
      checkedKeys,
      checkedNodes,
      indeterminate: false,
    });
  };

  _onClearAll = () => {
    this.setState({
      checkAll: false,
      indeterminate: false,
      checkedKeys: [],
      checkedNodes: [],
      expandedKeys: [],
    });
  };

  _onCheckTree = (val) => {
    const checkedNodes = [
        ...(this.state.checkedNodes || []).filter(
          (t) => !this.treeData.map((_t) => _t.key).includes(t.key),
        ),
        ...this.treeData.filter((x) => val.includes(x.key)),
      ],
      checkedKeys = checkedNodes.map((x) => x.key),
      checkAll =
        !!checkedKeys.length &&
        checkedKeys.length >= this.treeData.length &&
        this.treeData.every((t) => checkedKeys.includes(t.key)),
      indeterminate = !!checkedKeys.length && checkedKeys.length < this.treeData.length;
    this.setState({
      checkedKeys,
      checkedNodes,
      checkAll,
      indeterminate,
    });
  };

  _onExpandTree = (expandedKeys) => {
    this.setState({
      expandedKeys,
      autoExpandParent: false,
    });
  };

  _onRemove = (idx) => {
    let { checkedKeys, checkedNodes } = this.state;
    checkedNodes.splice(idx, 1);
    checkedKeys = checkedNodes.map((x) => x.key);
    const checkAll = !!checkedKeys.length && checkedKeys.length === this.leafNodes.length;
    this.setState({
      checkedKeys,
      checkedNodes,
      indeterminate: checkedKeys.length ? true : false,
      checkAll,
    });
  };

  _onCancel = () => {
    this.setState({
      visible: false,
    });
    this.props.onPress({ index: 0 });
  };

  _onOk = () => {
    const { checkedKeys, checkedNodes } = this.state;
    this.setState({
      visible: false,
    });
    this.props.onPress({
      index: 1,
      checkedKeys,
      checkedNodes,
    });
  };
  orderSort(obj1, obj2) {
    var a = obj1.title;
    var b = obj2.title;
    if (b > a) {
      return -1;
    } else if (b < a) {
      return 1;
    } else {
      return 0;
    }
  }
  render() {
    const { title = '结算单元' } = this.props;
    const {
      visible,
      checkAll,
      indeterminate,
      autoExpandParent,
      checkedKeys = [],
      checkedNodes = [],
      expandedKeys = [],
      searchValue = '',
    } = this.state;
    const loop = (data = []) =>
      data.map((item) => {
        const { lv, parentKey, key, disabled } = item;
        const index = item.title.indexOf(searchValue);
        const beforeStr = item.title.substr(0, index);
        const afterStr = item.title.substr(index + searchValue.length);
        const p_index = item.phone.indexOf(searchValue);
        const p_beforeStr = item.phone.substr(0, p_index);
        const p_afterStr = item.phone.substr(p_index + searchValue.length);
        const e_index = item?.email ? item.email.indexOf(searchValue) : null;
        const e_beforeStr = item?.email ? item.email.substr(0, e_index) : null;
        const e_afterStr = item?.email ? item.email.substr(e_index + searchValue.length) : null;
        let title =
          index > -1 ? (
            <span>
              {beforeStr}
              <span className={styles.search_act}>{searchValue}</span>
              {afterStr}
            </span>
          ) : (
            <span>{item.title}</span>
          );
        if (item.phone) {
          title = (
            <div style={{ paddingBottom: '13px' }}>
              {title}
              <p className={styles.label}>
                <MobileOutlined />
                <span style={{ paddingLeft: '7px' }}>
                  {p_index > -1 ? (
                    <span>
                      {p_beforeStr}
                      <span className={styles.search_act}>{searchValue}</span>
                      {p_afterStr}
                    </span>
                  ) : (
                    <span>{item.phone || '暂无'}</span>
                  )}
                </span>
              </p>
              <p className={styles.label}>
                <MailOutlined />
                <span style={{ paddingLeft: '7px' }}>
                  {e_index > -1 ? (
                    <span>
                      {e_beforeStr}
                      <span className={styles.search_act}>{searchValue}</span>
                      {e_afterStr}
                    </span>
                  ) : (
                    <span>{item.email || '暂无'}</span>
                  )}
                </span>
              </p>
            </div>
          );
        }
        if (item.children) {
          return { key, title, disabled, lv, parentKey, children: loop(item.children) };
        }

        return { key, title, disabled, lv, parentKey };
      });
    return (
      <Modal
        width={560}
        className={styles.modal}
        visible={visible}
        centered={true}
        maskClosable={true}
        title={
          <div key="title" className={styles.modal_title}>
            {title}
          </div>
        }
        onCancel={this._onCancel}
        okText={this.props.okText || '提交'}
        onOk={this._onOk}
      >
        {!this.allData.length ? (
          <div className={styles.emty}>
            <TRDefault type="emptysm" />
          </div>
        ) : (
          <div className={styles.modal_body}>
            <div className={styles.treebox}>
              <div className={styles.box_header}>
                <Input
                  placeholder="搜索"
                  suffix={<SearchOutlined />}
                  allowClear={true}
                  onChange={this._onSearch}
                />
              </div>
              <div className={`${styles.box_content} ${styles.traderBox}`}>
                <Checkbox
                  checked={checkAll}
                  indeterminate={indeterminate}
                  onChange={this._onChangeAll}
                >
                  全选
                </Checkbox>
                <Tree
                  treeData={loop(this.treeData)}
                  blockNode={true}
                  checkable={true}
                  selectable={false}
                  checkedKeys={checkedKeys}
                  expandedKeys={expandedKeys}
                  autoExpandParent={autoExpandParent}
                  onExpand={this._onExpandTree}
                  onCheck={this._onCheckTree}
                  height={250}
                  ref={(e) => (this.refTree = e)}
                />
              </div>
            </div>

            <div className={styles.choosebox}>
              <div className={styles.box_header}>
                <div>{`已选${checkedNodes.length}项`}</div>
                <div className={styles.clear} onClick={this._onClearAll}>
                  清空
                </div>
              </div>
              <div className={styles.box_content}>
                <ul className={styles.chooseList}>
                  {checkedNodes.sort(this.orderSort).map((item, idx) => {
                    return (
                      <li key={item.key}>
                        <div className={styles.chooseName}>
                          <p>{item.title}</p>
                          <p className={styles.label}>
                            <MobileOutlined />
                            <span style={{ paddingLeft: '7px' }}>{item.phone || '暂无'}</span>
                          </p>
                          <p className={styles.label}>
                            <MailOutlined />
                            <span style={{ paddingLeft: '7px' }}>{item.email || '暂无'}</span>
                          </p>
                        </div>
                        <CloseOutlined
                          className={styles.close}
                          onClick={this._onRemove.bind(this, idx)}
                        />
                      </li>
                    );
                  })}
                </ul>
              </div>
            </div>
          </div>
        )}
      </Modal>
    );
  }
}

class TRCheckboxModal {
  __key__ = '';

  show = (props) => {
    return new Promise((resolve) => {
      if (this.__key__ !== '') return;
      this.__key__ = String(Date.now());
      TRNotification.add({
        key: this.__key__,
        content: (
          <ModalComponent
            {...props}
            onPress={(result) => {
              TRNotification.remove(this.__key__);
              this.__key__ = '';
              resolve(result);
            }}
          />
        ),
        duration: null,
      });
    });
  };

  dismiss = () => {
    if (this.__key__.length > 0) {
      TRNotification.remove(this.__key__);
      this.__key__ = '';
    }
  };
}

export default new TRCheckboxModal();
